package dmwr.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import dmwr.Dmwr;
import dmwr.bean.User;
import dmwr.context.Context;
import dmwr.util.Operation;
import dmwr.util.Passwords;
import dmwr.web.Http;

public class Secure implements Filter {

	// private static final ThreadLocal<User> CURRENT_USER = new
	// ThreadLocal<User>();

	private static final ThreadLocal<Context> CONTEXT = new ThreadLocal<Context>();

	// public static User currentUser() {
	// return CURRENT_USER.get();
	// }

	public static Context context() {
		return CONTEXT.get();
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			final FilterChain chain) throws IOException, ServletException {
		Http.execute(new Operation<Object>() {

			@Override
			public Object execute() throws Exception {
				Http.request().setCharacterEncoding("UTF-8");
				CONTEXT.set(Dmwr.contextProvider().execute());
				try {
					Http.request().setAttribute("context", context());
					String uri = Http.request().getRequestURI();
					if ("/login".equals(uri) || context().getUser() != null) {
						chain.doFilter(Http.request(), Http.response());
						return null;
					}
					Cookie[] cookies = Http.request().getCookies();
					if (cookies != null) {
						for (Cookie cookie : cookies) {
							if ("remember".equals(cookie.getName())) {
								String username = cookie.getValue().substring(
										0, cookie.getValue().indexOf(' '));
								User user = Dmwr.service().getUser(username);
								if (user != null
										&& Passwords.check(cookie.getValue()
												.toCharArray(), user
												.getRememberSalt(), user
												.getRememberHash())) {
									Http.request().getSession()
											.setAttribute("user", user);
									chain.doFilter(Http.request(),
											Http.response());
									return null;
								}
							}
						}
					}
					Http.forward("/login.jsp");
				} finally {
					CONTEXT.set(null);
				}
				return null;
			}
		}, (HttpServletRequest) request, (HttpServletResponse) response);
	}

	@Override
	public void destroy() {
	}
}
